iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
  • 我們昨天提過 CNN 的結構就是兩層 卷積層 + 池化層 的結構,並在後面接一個簡單的 NN
  • 那就讓我們來看看 PyTorch 有什麼辦法做到上面的狀況吧~

PyTorch CNN

  • 第一步當然是建立 Model 框架
class ConvNet(nn.Module):

    def __init__(self):
        # model layers
        
    def forward(self, x):
        # model structure
  • 那首先我們要把第一層的卷積層跟池化層做出來,因此我們要分別宣告 nn.Conv2dnn.MaxPool2d,那位啥這邊是使用 MaxPool 的原因我們昨天有解釋過了,那我們先看 code 在解釋一下裡面的參數
  • 下面的程式碼是基於手寫辨識資料集做撰寫的,後面我們對照資料集應該會更加理解,我們先解釋要注意哪些部份來建立 CNN
import torch
import torch.nn as nn
import torch.nn.functional as F

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        # image shape is 1 * 28 * 28, where 1 is one color channel
        # 28 * 28 is the image size
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=5)    # output shape = 3 * 24 * 24
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)                       # output shape = 3 * 12 * 12
        # intput shape is 3 * 12 * 12
        self.conv2 = nn.Conv2d(in_channels=3, out_channels=9, kernel_size=5)    # output shape = 9 * 8 * 8
        # add another max pooling, output shape = 9 * 4 * 4
        self.fc1 = nn.Linear(9*4*4, 100)
        self.fc2 = nn.Linear(100, 50)
        # last fully connected layer output should be same as classes
        self.fc3 = nn.Linear(50, 10)

        
    def forward(self, x):
        # first conv
        x = self.pool(F.relu(self.conv1(x)))
        # second conv
        x = self.pool(F.relu(self.conv2(x)))
        # flatten all dimensions except batch
        x = torch.flatten(x, 1)
        # fully connected layers
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)

        return x
  • 那我們一個一個來看,首先我們宣告了第一個卷積層,那卷積層中有幾個基本參數要給,分別是
    • in_channels:輸入的圖片通道數,這邊大部分會是圖片的顏色狀況,例如灰階圖片只有一個通道,RGB 的圖片會有三個通道
    • out_channels:輸出的通道數,這邊基本上沒有特別的限制,可以視自己喜好給予,只要記住往下一層送時,這邊會變成另外一層的 in_channels
    • kernel_size:這也就是我們的 feature filter 的 size,有兩種表達參數的方式,
      • 第一是如上面示範一樣,給予單參數,會被視為 num * num 的 feature filter
      • 另一種是寫成 kernel_size = (num1, num2) 就會是 num1 * num2 的 feature filter,請注意,feature filter 並沒有規定一定要是正方形,因此可以視喜好調整
    • stride:在 feature filter 遍歷圖片時,每次移動的步數可以不是一格一格移動,此參數就會設定每次卷積移動的步伐大小,那預設會是 1,因此我們上面沒有特別調整
  • 那這樣我們就可以設定好一個卷積層要做的行為了,第二步就是給予池化層,那池化層一樣有些參數可以給,分別是
    • kernal_size:同上敘述的,也就是 pooling 每次要覆蓋的資料量
    • stride:同上敘述,也就是池化每次的步數
  • 那我們在註解的部分已經有說明了每個行為之後的資料形狀,因此應該有輔助大家理解每一個操作之後的資料狀況
  • 那我們在做完兩次卷積+池化之後,我們要攤平資料並丟到 fully connected 做訓練,這個部分可以是任意簡單的神經網絡,因此我們這邊設計成一個三層的 feed-forward network
  • 最後依照整個流程把神經網絡的 forward 建立起來就建立好資料了~

每日小結

  • 到今天我們成功建立了一個在深度學習領域中有代表性地位的神經網絡架構,到這裡還是要強調一句,為何我們前面要時常強調基礎概念一定要建立好,因為到今天我們整個架構的建立,仍然沒有脫離對神經網絡架構的建立重現,因此只要我們知道整個網絡架構,要實現是非常非常簡單的
  • 我們到這裡也算是達到深度學習領域的一個小里程碑了,那最後最後當然要使用看看 CNN 的威力來致敬這個偉大的神經網絡啦~從明天開始就讓我們開始辨識手寫數字吧~

上一篇
Day-24 一定會見面,Convolutional Neural Network (CNN)
下一篇
Day-26 手把手的手寫辨識模型 0x1:資料集整理
系列文
Deep Learning 從零開始到放棄的 30 天 PyTorch 數字辨識模型31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言